﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/// <summary>
/// 数据处理
/// </summary>
public class DataProcessing  {
    
    /// <summary>
    /// 字符串转十六进制byte数组
    /// </summary>
    /// <param name="hexString"></param>
    /// <returns></returns>
    public static byte[] StringToHexBytes(string hexString)
    {
        hexString = hexString.Replace(" ", "");
        if ((hexString.Length % 2) != 0)
            hexString += " ";
        byte[] returnBytes = new byte[hexString.Length / 2];
        
        for (int i = 0; i < returnBytes.Length; i++)
        {
            returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
        }
        return returnBytes;
    }

    /// <summary>
    /// 字符串转十六进制byte数组自动计算校验码，仅限Modbus-RTU协议
    /// </summary>
    /// <param name="hexString"></param>
    /// <returns></returns>
    public static byte[] StringToHexBytesAutoCRC16(string hexString)
    {
        hexString += GetStringCRC16(hexString);
        hexString = hexString.Replace(" ", "");
        if ((hexString.Length % 2) != 0)
            hexString += " ";
        byte[] returnBytes = new byte[hexString.Length / 2];

        for (int i = 0; i < returnBytes.Length; i++){
            returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
        }
        return returnBytes;
    }

    /// <summary>
    /// 字符串数组转十六进制byte数组
    /// </summary>
    /// <param name="hexString"></param>
    /// <returns></returns>
    public static byte[] StringsToHexByte(string[] hexString)
    {
        byte[] returnBytes = new byte[hexString.Length];

        for (int i = 0; i < returnBytes.Length; i++)
        {
            returnBytes[i] = StringToHexByte(hexString[i]);
        }

        return returnBytes;
    }
    
    /// <summary>
    /// 字符串转十六进制byte
    /// </summary>
    /// <param name="hexString"></param>
    /// <returns></returns>
    public static byte StringToHexByte(string hexString)
    {
        hexString = hexString.Replace(" ", "");
        return Convert.ToByte(hexString.Substring(0, 2), 16);
    }

    /// <summary>
    /// 字符串转十六进制Int
    /// </summary>
    /// <param name="hexString"></param>
    /// <returns></returns>
    public static int StringToHexInt(string hexString)
    {
        hexString = hexString.Replace(" ", "");
        return Convert.ToInt32(hexString, 16);
    }

    /// <summary>
    /// CRC校验，参数为空格或逗号间隔的字符串
    /// </summary>
    /// <param name="data">校验数据，逗号或空格间隔的16进制字符串(带有0x或0X也可以),逗号与空格不能混用</param>
    /// <returns></returns>
    static string GetStringCRC16(string data)
    {
        //分隔符是空格还是逗号进行分类，并去除输入字符串中的多余空格
        IEnumerable<string> datac = data.Contains(",") ? data.Replace(" ", "").Replace("0x", "").Replace("0X", "").Trim().Split(',') : data.Replace("0x", "").Replace("0X", "").Split(' ').ToList().Where(u => u != "");
        List<byte> bytedata = new List<byte>();
        foreach (string str in datac)
        {
            bytedata.Add(byte.Parse(str, System.Globalization.NumberStyles.AllowHexSpecifier));
        }
        byte[] crcbuf = bytedata.ToArray();
        //crc计算赋初始值
        int crc = 0xffff;
        for (int i = 0; i < crcbuf.Length; i++)
        {
            crc = crc ^ crcbuf[i];
            for (int j = 0; j < 8; j++)
            {
                int temp;
                temp = crc & 1;
                crc = crc >> 1;
                crc = crc & 0x7fff;
                if (temp == 1)
                {
                    crc = crc ^ 0xa001;
                }
                crc = crc & 0xffff;
            }
        }
        //CRC寄存器的高低位进行互换
        byte[] crc16 = new byte[2];
        //CRC寄存器的高8位变成低8位
        crc16[1] = (byte)((crc >> 8) & 0xff);
        //CRC寄存器的低8位变成高8位
        crc16[0] = (byte)(crc & 0xff);

        string lowPos = crc16[1].ToString("X2");
        string hightPos = crc16[0].ToString("X2");

        return " " + hightPos + " " + lowPos;
    }

    /// <summary>
    /// 字节数组转16进制字符串：空格分隔
    /// </summary>
    /// <param name="byteDatas"></param>
    /// <returns></returns>
    public static string ToHexStrFromByte(byte[] byteDatas)
    {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < byteDatas.Length; i++)
        {
            builder.Append(string.Format("{0:X2} ", byteDatas[i]));
        }
        return builder.ToString().Trim();
    }
}
